%% /usr/local/src/lcc/lcc-4.1.beta.7/README.FreeBSD, Wed Mar 28 07:25:25 2001
%% Edit by Nelson H. F. Beebe <beebe@math.utah.edu>

The triple test on 

	Intel Pentium II	FreeBSD 4.1.1

fails when 1rcc is used to compile code.  A debugging session shows
the problem:

% gdb /var/tmp/lcc/4.1.beta.7/x86/freebsd/1rcc
(gdb) run -target=x86/freebsd -v -g2 -A -s0.6 /tmp/lcc987330.i /tmp/lcc987331.s
1rcc in free(): warning: junk pointer, too high to make sense.
...
... set breakpoint in free and main.c:204 and rerun
...
(gdb) where full
#0  0x80d52eb in free ()
No symbol table info available.
#1  0x80c7a18 in freopen ()
No symbol table info available.
#2  0x8060d5d in main_init (argc=8, argv=0xbfbff1ec) at ../lcc-4.1.beta.7/src/main.c:204
        i = 8
        infile = 0xbfbff3b1 "/tmp/lcc987330.i"
        outfile = 0xbfbff3c2 "/tmp/lcc987331.s"
#3  0xbfbff1ec in ?? ()
No symbol table info available.
#4  0x202 in ?? ()
No symbol table info available.
(gdb) n
Single stepping until exit from function free, 
which has no line number information.
0x80d4d9c in isatty ()
(gdb) n
Single stepping until exit from function isatty, 
which has no line number information.
1rcc in free(): warning: junk pointer, too high to make sense.

Breakpoint 1, 0x80d5d15 in exit ()

When I linked the executables with the Electric Fence library,
-lefence, free() reported a junk pointer when called from that same
freopen() call.

A simple test file demonstrates the problem:

% cat roo.c
/***********************************************************************
[10-Mar-2001]
***********************************************************************/

#include <stdio.h>
#include <stdlib.h>

#if defined(__STDC__) || defined(__cplusplus)
#define ARGS(parenthesized_list) parenthesized_list
#else
#define ARGS(parenthesized_list) ()
#endif

#ifndef EXIT_SUCCESS
#define EXIT_SUCCESS 0
#endif

int	main ARGS((int argc, char* argv[]));

int
main(int argc, char* argv[])
{
    static char *outfile = "roo.out";
    if (freopen(outfile,"w",stdout) == NULL)
    {
	fprintf(stderr, "%s: can't write `%s'\n", argv[0], outfile);
	exit(EXIT_FAILURE);
    }

    printf("Hello, world\n");

    return (EXIT_SUCCESS);
}

% \rm roo.out ; lcc roo.c && ./a.out ; cat roo.out
a.out in free(): warning: malloc() has never been called.

I then changed the test file to this:

% cat roo.c
/***********************************************************************
[10-Mar-2001]
***********************************************************************/

#include <stdio.h>
#include <stdlib.h>

#if defined(__STDC__) || defined(__cplusplus)
#define ARGS(parenthesized_list) parenthesized_list
#else
#define ARGS(parenthesized_list) ()
#endif

#ifndef EXIT_SUCCESS
#define EXIT_SUCCESS 0
#endif

int	main ARGS((int argc, char* argv[]));

int
main(int argc, char* argv[])
{
    static char *outfile = "roo.out";
    char *p = malloc(1);
    if (freopen(outfile,"w",stdout) == NULL)
    {
	fprintf(stderr, "%s: can't write `%s'\n", argv[0], outfile);
	exit(EXIT_FAILURE);
    }

    printf("Hello, world\n");

    free(p);
    return (EXIT_SUCCESS);
}

% \rm roo.out ; lcc roo.c && ./a.out ; cat roo.out
a.out in free(): warning: junk pointer, too high to make sense.

This is the same error that I get with lcc!
However, neither cc nor gcc produce this problem:

% \rm roo.out ; gcc roo.c && ./a.out ; cat roo.out
Hello, world

% \rm roo.out ; cc roo.c && ./a.out ; cat roo.out
Hello, world

If I produce .s or .o files with lcc, then complete the job with gcc,
the same `junk pointer' error arises.

The problem is that on this system, the FILE struct contains an item
of type fpos_t which is long long, and lcc does not support long long.
Thus, the size of the structure is computed incorrectly, and thus, the
addresses of stdin and stdout are also wrong:

lcc:
	pushl $__sF+84
	pushl $.LC8

gcc:
	pushl $__sF+88
	pushl $.LC1

Solution: Provide an lcc-private version of stdio.h, adapted from 
          /usr/include/stdio.h.  Because the FILE* struct on this
	  system requires one element of type long long, which lcc
	  currently treats as long, the type of that element (_offset)
	  has been changed to long, and an extra dummy element
	  inserted.  With that change, the entire validation suite now
	  passes!  User programs that reference types fpos_t or off_t,
	  or call lseek(), fseeko(), or ftello(), will almost
	  certainly not work properly when compiled with lcc, until
	  "long long" support is fully implemented.
